using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Text;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;
using T.FAS.Runtime.Expression.SPI;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Expression.Entity;
//using T.FAS.Authority.RTP.Service;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using T.ServiceComponent.Kernel.Service;
using System.IO;
using T.FAS.Runtime.Metadata.Client;
using T.FAS.Runtime.Metadata.Entity;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.ServiceComponent.I18N.Service;
using System.Globalization;
using T.ServiceComponent.I18N.SPI;
using T.ServiceFramework.ServiceGateway.Client;
using AppContext = T.ServiceComponent.Session.Service.AppContext;
using System.Security.Cryptography;
using T.FAS.Runtime.Base.Common;
using System.Data;
using T.ServiceComponent.Common.Service;

namespace T.FAS.Runtime.Expression.Plugin
{
    public class FuncsExecutor : DynamicObject, IDynamicActionAdapter
    {
        readonly Region region = RegionService.Current.GetCurrentRegion();
        public FuncsExecutor() 
        {
            if(region == null)
            {
                region = new Region { Configs = new Dictionary<string, string>() };
            }
        }  
        /// <summary>
        /// JS脚本动态调用Dynamic必备函数
        /// 脚本写法：DQ.DQ_GetUser();
        /// </summary>
        /// <param name = "name">动态调用DynamicObject中的函数名称</param>
        /// <param name = "args">参数信息，参数类型必须增加 params</param>
        /// <returns></returns>
        public dynamic DynamicInvoke(string name, params object[] args)
        {
            return ExcuteFuncs(name, args);
        }

        private dynamic ExcuteFuncs(string actionID, object[] paramList)
        {
            switch (actionID)
            {
                case "SendMsgToGroup":
                    string title = Convert.ToString(paramList[0]);
                    string content = Convert.ToString(paramList[1]);
                    List<string> mobiles = JsonConvert.DeserializeObject<List<string>>(JsonConvert.SerializeObject(paramList[2]));
                    string accessToken = Convert.ToString(paramList[3]);
                    string secret = Convert.ToString(paramList[4]);
                    bool isAtAll = Convert.ToBoolean(paramList[5]);
                    SendMsgToGroup(title, content, mobiles, accessToken, secret, isAtAll);
                    return true;
                case "BuildDQAdvFilter":
                    string s = JsonConvert.SerializeObject(paramList);
                    List<AdvFilter> filters = JsonConvert.DeserializeObject<List<AdvFilter>>(s);
                    if (filters == null)
                    {
                        throw new FasException(ExprExceptionCode.InValidParam, $"{T.ServiceComponent.I18N.Service.TermService.Current.GetText("T_FAS_fasr_Expression_831220508", "BuildDQAdvFilter入参格式不正确")}");
                    }

                    return BuildDQAdvFilter(filters);
                case "Desensitize":
                    if (paramList.Length < 2)
                    {
                        throw new FasException(ExprExceptionCode.InValidParam, "Parameter mismatch Funcs." + actionID);
                    }
                    try
                    {
                        List<TRecord> rows = JsonConvert.DeserializeObject<List<TRecord>>(JsonConvert.SerializeObject(paramList[0]));
                        List<DesensitizationColumnSet> setlist = JsonConvert.DeserializeObject<List<DesensitizationColumnSet>>(JsonConvert.SerializeObject(paramList[1]));
                        return Desensitize(rows, setlist);
                    }
                    catch(Exception e)
                    {
                        throw new FasException(ExprExceptionCode.InValidParam, "Parameter format is incorrect.");
                    }
                default:
                    throw new FasException(ExprExceptionCode.NotSupported, "Unsupported Funcs." + actionID);
            }
        }

        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out dynamic result)
        {
            result = DynamicInvoke(binder.Name, args);
            return true;
        }

        #region Math
        public decimal Abs(decimal x) => Math.Abs(x);
        public decimal Mod(decimal x, decimal y) => x % y;
        public double Power(double x, double y) => Math.Pow(x, y);
        public decimal Round(decimal x) => Math.Round(x);
        public decimal Round(decimal x, int y) => Math.Round(x, y);
        public double Sqrt(double x) => Math.Sqrt(x);
        public double Trunc(double x) => Math.Floor(x);
        #endregion
        #region Numeric
        public double Max(double x, double y) => Math.Max(x, y);
        public double Min(double x, double y) => Math.Min(x, y);
        public int Sign(double x) => Math.Sign(x);
        #endregion
        #region String
        public char Chr(int x) => (char)x;
        public string Concat(string x, string y) => x + y;
        public string EncodeHtml(string str) => HttpUtility.HtmlEncode(str);
        public string EncodeUrl(string str) => HttpUtility.UrlEncode(str);
        public string Guid() => System.Guid.NewGuid().ToString();
        public int Length(string str)
        {
            return str.Length;
        }
        public bool Contains(string str, string key)
        {
            return str.Contains(key);
        }
        public string Replace(string str, string search, string replace) => str.Replace(search, replace);
        public string Substr(string str, int start, int length) => str.Substring(start, length);
        public string ToLower(string str) => str.ToLower();
        public string ToUpper(string str) => str.ToUpper();
        public string Trim(string str) => str.Trim();
        public string TrimEnd(string str) => str.TrimEnd();
        public string TrimStart(string str) => str.TrimStart();
        #endregion
        #region Date and Time
        public string AddDays(object dt, int n) => ConvertToDateTime(Convert.ToString(dt)).AddDays(n).ToString("yyyy-MM-dd HH:mm:ss");
        public string AddHours(object dt, int n) => ConvertToDateTime(Convert.ToString(dt)).AddHours(n).ToString("yyyy-MM-dd HH:mm:ss");
        public string AddMinutes(object dt, int n) => ConvertToDateTime(Convert.ToString(dt)).AddMinutes(n).ToString("yyyy-MM-dd HH:mm:ss");
        public string AddMonths(object dt, int n) => ConvertToDateTime(Convert.ToString(dt)).AddMonths(n).ToString("yyyy-MM-dd HH:mm:ss");
        public string AddSeconds(object dt, int n) => ConvertToDateTime(Convert.ToString(dt)).AddSeconds(n).ToString("yyyy-MM-dd HH:mm:ss");
        public string AddYears(object dt, int n) => ConvertToDateTime(Convert.ToString(dt)).AddYears(n).ToString("yyyy-MM-dd HH:mm:ss");
        public string BuildDateTime(object dt, object t) => ConvertToDateTime(Convert.ToString(dt)).ToString("yyyy-MM-dd") + " " + ConvertToDateTime(Convert.ToString(t)).ToString("HH:mm:ss");
        public string CurrDate()
        {
            return DateTime.Now.ToString("yyyy-MM-dd");
        }

        public string CurrDateTime() => DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
        public string CurrTime() => DateTime.Now.ToString("HH:mm:ss");
        public int Day(object dt) => ConvertToDateTime(Convert.ToString(dt)).Day;
        public int DayOfWeek(object dt) => (int)ConvertToDateTime(Convert.ToString(dt)).DayOfWeek;
        public double DiffDays(object dt1, object dt2) => (ConvertToDateTime(Convert.ToString(dt2)) - ConvertToDateTime(Convert.ToString(dt1))).TotalDays;
        public double DiffHours(object dt1, object dt2) => (ConvertToDateTime(Convert.ToString(dt2)) - ConvertToDateTime(Convert.ToString(dt1))).TotalHours;
        public double DiffMinutes(object dt1, object dt2) => (ConvertToDateTime(Convert.ToString(dt2)) - ConvertToDateTime(Convert.ToString(dt1))).TotalMinutes;
        public double DiffSeconds(object dt1, object dt2) => (ConvertToDateTime(Convert.ToString(dt2)) - ConvertToDateTime(Convert.ToString(dt1))).TotalSeconds;
        public int Hour(object dt) => ConvertToDateTime(Convert.ToString(dt)).Hour;
        public int Minute(object dt) => ConvertToDateTime(Convert.ToString(dt)).Minute;
        public int Month(object dt) => ConvertToDateTime(Convert.ToString(dt)).Month;
        public string NewDate(int year, int month, int day) => new DateTime(year, month, day).ToString("yyyy-MM-dd");
        public string NewDateTime(int year, int month, int day, int hours, int minutes, int seconds) => new DateTime(year, month, day, hours, minutes, seconds).ToString("yyyy-MM-dd HH:mm:ss");
        public string NewDateTime(int hours, int minutes, int seconds) => new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hours, minutes, seconds).ToString("HH:mm:ss");
        public int Second(object dt) => ConvertToDateTime(Convert.ToString(dt)).Second;
        public int Year(object dt) => ConvertToDateTime(Convert.ToString(dt)).Year;
        public string GetDateDiff(object dt)
        {
            TimeSpan span = DateTime.Now - ConvertToDateTime(Convert.ToString(dt));
            if (span.TotalDays >= 30)
            {
                return string.Format($"{T.ServiceComponent.I18N.Service.TermService.Current.GetText("T_FAS_fasr_Expression_549284082", "{0}月前")}", (int)Math.Floor(span.TotalDays / 30));
            }
            else if (span.TotalDays >= 7)
            {
                return string.Format($"{T.ServiceComponent.I18N.Service.TermService.Current.GetText("T_FAS_fasr_Expression_310347304", "{0}周前")}", (int)Math.Floor(span.TotalDays / 7));
            }
            else if (span.TotalDays >= 1)
            {
                return string.Format($"{T.ServiceComponent.I18N.Service.TermService.Current.GetText("T_FAS_fasr_Expression_1370110342", "{0}天前")}", (int)Math.Floor(span.TotalDays));
            }
            else if (span.TotalHours >= 1)
            {
                return string.Format($"{T.ServiceComponent.I18N.Service.TermService.Current.GetText("T_FAS_fasr_Expression_1568206226", "{0}小时前")}", (int)Math.Floor(span.TotalHours));
            }
            else if (span.TotalMinutes >= 1)
            {
                return string.Format($"{T.ServiceComponent.I18N.Service.TermService.Current.GetText("T_FAS_fasr_Expression_1385299872", "{0}分钟前")}", (int)Math.Floor(span.TotalMinutes));
            }
            else
            {
                return $"{T.ServiceComponent.I18N.Service.TermService.Current.GetText("T_FAS_fasr_Expression_1482651760", "刚刚")}";
            }
        }
        /// <summary>
        /// 获取对应日期本年的第一天
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string GetFisrtDayOfTheYear(object dt)
        {
            return new DateTime(ConvertToDateTime(Convert.ToString(dt)).Year, 1, 1).ToString("yyyy-MM-dd 00:00:00");
        }
        public string GetFirstDayOfTheYear(object dt)
        {
            return new DateTime(ConvertToDateTime(Convert.ToString(dt)).Year, 1, 1).ToString("yyyy-MM-dd 00:00:00");
        }
        /// <summary>
        /// 获取对应日期本年的最后一天
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string GetLastDayOfTheYear(object dt)
        {
            return new DateTime(ConvertToDateTime(Convert.ToString(dt)).Year, 12, 31).ToString("yyyy-MM-dd 23:59:59");
        }
        public string GetFisrtDayOfTheQuarter(object dt)
        {
            var dateTime = ConvertToDateTime(Convert.ToString(dt));
            return dateTime.AddMonths(0 - (dateTime.Month - 1) % 3).AddDays(1 - dateTime.Day).ToString("yyyy-MM-dd 00:00:00");
        }
        /// <summary>
        /// 获取对应日期季度的最后一天
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string GetFirstDayOfTheQuarter(object dt)
        {
            var dateTime = ConvertToDateTime(Convert.ToString(dt));
            return dateTime.AddMonths(0 - (dateTime.Month - 1) % 3).AddDays(1 - dateTime.Day).ToString("yyyy-MM-dd 00:00:00");
        }
        public string GetLastDayOfTheQuarter(object dt)
        {
            var dateTime = ConvertToDateTime(Convert.ToString(dt));
            return dateTime.AddMonths(3 - (dateTime.Month - 1) % 3).AddDays(-dateTime.Day).ToString("yyyy-MM-dd 23:59:59");
        }
        /// <summary>
        /// 获取对应日期季度的第一天
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string GetFisrtDayOfTheMonth(object dt)
        {
            var dateTime = ConvertToDateTime(Convert.ToString(dt));
            return new DateTime(dateTime.Year, dateTime.Month, 1).ToString("yyyy-MM-dd 00:00:00");
        }
        public string GetFirstDayOfTheMonth(object dt)
        {
            var dateTime = ConvertToDateTime(Convert.ToString(dt));
            return new DateTime(dateTime.Year, dateTime.Month, 1).ToString("yyyy-MM-dd 00:00:00");
        }
        /// <summary>
        /// 获取对应日期月度的最后一天
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string GetLastDayOfTheMonth(object dt)
        {
            var dateTime = ConvertToDateTime(Convert.ToString(dt));
            return new DateTime(dateTime.Year, dateTime.Month, 1).AddMonths(1).AddDays(-1).ToString("yyyy-MM-dd 23:59:59");
        }
        /// <summary>
        /// 获取对应日期周的第一天
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string GetFisrtDayOfTheWeek(object dt)
        {
            var dateTime = ConvertToDateTime(Convert.ToString(dt));
            int dayOfWeek = -1 * (int)dateTime.DayOfWeek;
            if (dayOfWeek == 0)
            {
                return dateTime.AddDays(-6).ToString("yyyy-MM-dd 00:00:00");
            }

            return dateTime.AddDays(dayOfWeek + 1).ToString("yyyy-MM-dd 00:00:00");
        }
        public string GetFirstDayOfTheWeek(object dt)
        {
            var dateTime = ConvertToDateTime(Convert.ToString(dt));
            int dayOfWeek = -1 * (int)dateTime.DayOfWeek;
            if (dayOfWeek == 0)
            {
                return dateTime.AddDays(-6).ToString("yyyy-MM-dd 00:00:00");
            }

            return dateTime.AddDays(dayOfWeek + 1).ToString("yyyy-MM-dd 00:00:00");
        }
        /// <summary>
        /// 获取对应日期周的最后一天
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string GetLastDayOfTheWeek(object dt)
        {
            var dateTime = ConvertToDateTime(Convert.ToString(dt));
            int dayOfWeek = -1 * (int)dateTime.DayOfWeek;
            if (dayOfWeek == 0)
            {
                return dateTime.ToString("yyyy-MM-dd 23:59:59");
            }

            return dateTime.AddDays(dayOfWeek + 7).ToString("yyyy-MM-dd 23:59:59");
        }
        /// <summary>
        /// 获取对应周数的第一天
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string GetFisrtDayOfTheWeekByWeekNo(int year, int weekNum)
        {
            // 此年1号是星期几
            DateTime dateTime = new DateTime(year, 1, 1);
            return GetFisrtDayOfTheWeek(dateTime.AddDays((weekNum - 1) * 7));
        }
        public string GetFirstDayOfTheWeekByWeekNo(int year, int weekNum)
        {
            // 此年1号是星期几
            DateTime dateTime = new DateTime(year, 1, 1);
            return GetFirstDayOfTheWeek(dateTime.AddDays((weekNum - 1) * 7));
        }
        /// <summary>
        /// 获取对应周数的第一天
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string GetLastDayOfTheWeekByWeekNo(int year, int weekNum)
        {
            // 此年1号是星期几
            DateTime dateTime = new DateTime(year, 1, 1);
            return GetLastDayOfTheWeek(dateTime.AddDays((weekNum - 1) * 7));
        }

        public int GetWeekNum(object dt)
        {
            var dateTime = ConvertToDateTime(Convert.ToString(dt));
            DateTime firstDay = new DateTime(dateTime.Year, 1, 1);
            int dayCount = (int)(dateTime - firstDay).TotalDays;
            dayCount += Convert.ToInt32(firstDay.DayOfWeek);
            return (int)Math.Ceiling(dayCount / 7.0);
        }

        #endregion
        #region Data Conversion
        public int BooleanToInt(bool b) => b ? 1 : 0;
        public string BooleanToString(bool b) => b ? "true" : "false";
        public string DateTimeToDate(object dt) => ConvertToDateTime(Convert.ToString(dt)).ToString("yyyy-MM-dd");
        public string DateTimeToString(object dt)
        {
            return ConvertToDateTime(Convert.ToString(dt)).ToString(region.DateTimeFormat);
        } 
        public string DateTimeToTime(object dt)
        {
            return ConvertToDateTime(Convert.ToString(dt)).ToString(region.TimeFormat);
        }
        public string DateToDateTime(object dt)
        {
            return ConvertToDateTime(Convert.ToString(dt)).ToString(region.DateTimeFormat);
        }
        public string DateToString(object dt)
        {
            return ConvertToDateTime(Convert.ToString(dt)).ToString(region.DateFormat);
        } 
        public bool DecimalToBoolean(decimal d) => d != 0;
        public int DecimalToInt(decimal d) => Convert.ToInt32(d);
        public long DecimalToLong(decimal d) => Convert.ToInt64(d);
        public string DecimalToString(decimal d)
        {
            IValueConvertService valueConvertService = I18NService.GetValueConvertService();
            return valueConvertService.ConvertDecimalToString(d);
        }
        public int LongToInt(long d) => Convert.ToInt32(d);
        public string LongToString(long l) => l.ToString();
        public bool IntToBoolean(int i) => i != 0;
        public decimal IntToDecimal(int i) => Convert.ToDecimal(i);
        public string IntToString(int i) => i.ToString();
        public DateTime ConvertToDateTime(string dateString)
        {
            DateTime result;

            // 添加更多可能的时间格式
            if(DateTime.TryParse(dateString,out DateTime dt))
            {
                return dt;
            }
            else
            {
                CultureInfo cultureInfo;
                if (AppContext.Current.Language == null)
                {
                    cultureInfo = new CultureInfo("zh-CN");
                }
                else
                {
                    cultureInfo = new CultureInfo(AppContext.Current.Language.ID);
                }
                string[] formats = cultureInfo.DateTimeFormat.GetAllDateTimePatterns();
                string[] newArray = new string[formats.Length + 1];
                Array.Copy(formats, newArray, formats.Length);
                newArray[newArray.Length - 1] = "ddd MMM dd yyyy HH:mm:ss 'GMT'zzz";
                if (DateTime.TryParseExact(dateString, newArray, CultureInfo.InvariantCulture, DateTimeStyles.None, out result))
                {
                    return result;
                }
            }
            throw new FormatException($"Unrecognized date/time format {dateString}");
        }
        public string NumberToString(decimal value)
        {
            IValueConvertService valueConvertService = I18NService.GetValueConvertService();
            return valueConvertService.ConvertDecimalToString(value);
        }
        public string StringToDate(object dt) => ConvertToDateTime(Convert.ToString(dt)).ToString("yyyy-MM-dd");
        public string StringToDateTime(object dt) => ConvertToDateTime(Convert.ToString(dt)).ToString("yyyy-MM-dd HH:mm:ss");
        public string StringToTime(object dt) => ConvertToDateTime(Convert.ToString(dt)).ToString("HH:mm:ss");
        public decimal StringToDecimal(string s) => Convert.ToDecimal(s);
        public int StringToInt(string s) => Convert.ToInt32(s);
        public long StringToLong(string s) => Convert.ToInt64(s);
        public string TimeToString(object dt)
        {
            return ConvertToDateTime(Convert.ToString(dt)).ToString(region.TimeFormat);
        }
        #endregion
        #region Format
        public string FormatCurrency(decimal number, int places, string symbol, string thousand, string dec)
        {
            return symbol + FormatDecimal(number, places, thousand, dec);
        }

        public string TryFormatDateTime(string dt, string fmt)
        {
            DateTime dateTime;
            bool isConvert = DateTime.TryParse(dt, out dateTime);
            if (isConvert)
                return dateTime.ToString(fmt);
            return new DateTime(1, 1, 1).ToString(fmt);
        }
        public string FormatDateTime(object dt, string fmt)
        {
            return ConvertToDateTime(Convert.ToString(dt)).ToString(fmt);
        }

        public string GetHashID(string s)
        {
            using (MD5 md5Hash = MD5.Create())
            {
                byte[] bytes = Encoding.UTF8.GetBytes(s);
                byte[] hashBytes = md5Hash.ComputeHash(bytes);
                return BitConverter.ToString(hashBytes);
            }
        }

        public int GetThousand(int s)
        {
            return (s > 3) ? GetThousand(s % 3) : s;
        }

        public int GetThreadID()
        {
            return System.Threading.Thread.CurrentThread.ManagedThreadId;
        }

        public string GetRequestID()
        {
            return RpcContext.Current.RequestID;
        }

        public string GetRpcID()
        {
            return RpcContext.Current.RpcID;
        }

        public string FormatDecimal(decimal number, int places, string thousand, string dec)
        {
            return string.Format("{0:N" + places + "}", number).Replace(".", "@").Replace(",", thousand).Replace("@", dec);
        }

        public string FormatPercent(decimal number, int places, string thousand)
        {
            return string.Format("{0:N" + places + "}", number).Replace(",", thousand);
        }

        #endregion
        #region Miscellaneous
        /// <summary>
        /// 获取词条翻译
        /// </summary>
        /// <param name = "termCode"></param>
        /// <param name = "orginalText"></param>
        /// <returns></returns>
        public string GetTerms(string termCode, string orginalText = null)
        {
            return TermService.Current.GetTextFormatted(termCode, orginalText);
        }
        public bool TryBoolean(string value)
        {
            switch (value.ToLower())
            {
                case "1":
                case "true":
                    return true;
                case "0":
                case "false":
                    return false;
                default:
                    throw new FasException(ExprExceptionCode.ErrorExpr,$"{value}转换bool类型失败");
            }
        }
        public string GeneratePassword(int l, bool alpha)
        {
            var t = "1234567890".ToArray();
            var n = new StringBuilder();
            if (alpha)
            {
                t = "ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890".ToArray();
            }

            for (var i = 0; i < l; i++)
                n.Append( t[new Random().Next(t.Length)]);
            return n.ToString();
        }

        public object If(bool value, object true_return, object false_return) => value ? true_return : false_return;
        public bool HasOP(string bpoId, string opCode)
        {
            /* Todo
            BizOperationService bizOperationService = new BizOperationService();
            return bizOperationService.HasBizOperation(bpoId, opCode);
            */
            return true;
        }
        /// <summary>
        /// 获取权限
        /// </summary>
        public string GetAuthSQL(string userId, string functionId)
        {
            /* Todo
            IDataPermissionsService permissionsService = DataPermissionsService.GetInstance();
            return permissionsService.GetFilterSqlByUserId(userId, functionId).Replace("with(nolock)", "");
            */
            return "1=1";
        }
        public bool IsNull(object obj)
        {
            if (obj == null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool IsNullOrEmpty(object obj)
        {
            if (obj == null || Convert.ToString(obj) == "")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public string GetNodeError()
        {
            string filePath = "C:\\Users\\t\\logs\\T.FAS.RP.NODEJS\\common-error.log";
            
            List<string> fileContent = new List<string>();
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            using (StreamReader sr = new StreamReader(fs))
            {
                // 定位到文件末尾
                string line = "0";
                while (line != null)
                {
                    line = sr.ReadLine();
                    fileContent.Add(line);
                }
            }
            StringBuilder text = new StringBuilder();
            int start = fileContent.Count > 100 ? fileContent.Count - 100 : 0;
            for (int i = start; i < fileContent.Count; i++)
            {
                if (text.Length == 0 && !fileContent[i].StartsWith("hostname"))
                    continue;
                text.AppendLine(fileContent[i]);
            }
            return text.ToString();
        }
        public string GetNoteText(string path)
        {
            string[] strFile = File.ReadAllLines(path);
            StringBuilder text = new StringBuilder();
            int lineCount = strFile.Length;
            int start = lineCount > 1000 ? lineCount - 1000 : 0;
            for (int i = start; i < lineCount; i++)
            {
                text.AppendLine(strFile[i]);
            }
            return text.ToString();
        }
        /*
    public void SendMsgToUser(string UserId, string content)
    {
         * var notifyService = HSFService.Proxy<INotifyService>();
        string dingDingUserID = UserUtil.GetDingDingIdByUserId(UserId);
        if (string.IsNullOrEmpty(dingDingUserID))
        {
            throw new FasException(ExprExceptionCode.UnFounded, $"{T.ServiceComponent.I18N.Service.TermService.Current.GetTextFormatted("T_FAS_fasr_Expression_1012988199", "获取用户{0}钉钉ID失败", UserId)}");
        }
        if (content?.Length > 4500)
        {
            LogUtil.Log(content, "Expression");
            content = content.Substring(0, 4500) + "...";
        }
        IExtendMessageUser messageUser = new DDMessageReceiver
        {
            user = new CommonUser()
            { UserID = dingDingUserID }
        };
        INotifyMessage message = new DDMessage { Content = "{\"title\": \"" + $"{T.ServiceComponent.I18N.Service.TermService.Current.GetText("T_FAS_fasr_Expression_352810827", "钉钉提醒")}" + "\", \"text\": \"" + content + "\"}", ContentType = MessageContentType.markdown, };
        var notifyContext = new NotifyContext
        {
            ModelFlag = "ExprDD",
            NotifyConfig = new DDNotifyConfig()
            { AgentID = UserUtil.DingTalkAgentID, ModelFlag = "ExprDD" }
        };
        notifyService.SendNewUserMessageAsync(messageUser, null, message, notifyContext);

    }
    public void SendMsgToUser(string UserId, string content,string agentID)
    {
        var notifyService = HSFService.Proxy<INotifyService>();
        string dingDingUserID = UserUtil.GetDingDingIdByUserId(UserId);
        if (string.IsNullOrEmpty(dingDingUserID))
        {
            throw new FasException(ExprExceptionCode.UnFounded, $"{T.ServiceComponent.I18N.Service.TermService.Current.GetTextFormatted("T_FAS_fasr_Expression_1012988199", "获取用户{0}钉钉ID失败", UserId)}");
        }
        if (content?.Length > 4500)
        {
            LogUtil.Log(content, "Expression");
            content = content.Substring(0, 4500) + "...";
        }
        IExtendMessageUser messageUser = new DDMessageReceiver
        {
            user = new CommonUser()
            { UserID = dingDingUserID }
        };
        INotifyMessage message = new DDMessage { Content = "{\"title\": \"" + $"{T.ServiceComponent.I18N.Service.TermService.Current.GetText("T_FAS_fasr_Expression_352810827", "钉钉提醒")}" + "\", \"text\": \"" + content + "\"}", ContentType = MessageContentType.markdown, };
        var notifyContext = new NotifyContext
        {
            ModelFlag = "ExprDD",
            NotifyConfig = new DDNotifyConfig()
            { AgentID = agentID, ModelFlag = "ExprDD" }
        };
        notifyService.SendNewUserMessageAsync(messageUser, null, message, notifyContext);
    }*/
        public object BuildMockRecordData(string metadataId)
        {
            var instance = MetaDataClientService.GetInstance();
            IMetaDataContent content = instance.GetMetaDataContent(metadataId);
            if (content is DataObject dataObject)
            {
                return GetRecord(dataObject.BuildSchema(), 0);
            }
            else if (content is CompositeDataObject cdo)
            {
                return GetRecord(cdo.BuildSchema(), 0);
            }
            else if (content is DataQuery dataQuery)
            {
                return GetRecord(dataQuery.BuildSchema(), 0);
            }
            else if (content is EntityObject entityObject)
            {
                return GetRecord(entityObject.BuildSchema(), 0);
            }
            else
            {
                throw new FasException(ExprExceptionCode.ErrorExpr, $"获取元数据失败{metadataId}");
            }
        }
        public object BuildMockListData(string metadataId, int num = 10)
        {
            var instance = MetaDataClientService.GetInstance();
            IMetaDataContent content = instance.GetMetaDataContent(metadataId);
            if (content is DataObject dataObject)
            {
                return GetListRecord(dataObject.BuildSchema(), num);
            }
            else if (content is CompositeDataObject cdo)
            {
                return GetListRecord(cdo.BuildSchema(), num);
            }
            else if (content is DataQuery dataQuery)
            {
                return GetListRecord(dataQuery.BuildSchema(), num);
            }
            else if (content is EntityObject entityObject)
            {
                return GetListRecord(entityObject.BuildSchema(), num);
            }
            else
            {
                throw new FasException(ExprExceptionCode.ErrorExpr, $"获取元数据失败{metadataId}");
            }
        }
        private List<TRecord> GetListRecord(TSchema schema, int num)
        {
            List<TRecord> list = new List<TRecord>();
            for (int i = 1; i < num + 1; i++)
            {
                TRecord record = GetRecord(schema, i);
                list.Add(record);
            }
            return list;
        }
        private TRecord GetRecord(TSchema schema, int index)
        {
            var random = new Random();
            var dic = new Dictionary<string, object>();
            InitRecord(schema.Entity, dic, random, index);
            return new TRecord(dic);
        }
        private void InitRecord(TEntity entity, Dictionary<string, object> dic, Random random, int index)
        {
            foreach (var item in entity.Attributes)
            {
                switch (item.DataType)
                {
                    case DataType.Int:
                    case DataType.Long:
                        dic.Add(item.Code, random.Next(999));
                        break;
                    case DataType.Boolean:
                        dic.Add(item.Code, random.Next(0, 2) == 1);
                        break;
                    case DataType.Decimal:
                        dic.Add(item.Code, random.Next(9999999));
                        break;
                    case DataType.Date:
                    case DataType.Time:
                        dic.Add(item.Code, DateTime.Now.AddDays(random.Next(-90, 1)).ToString("yyyy-MM-dd"));
                        break;
                    case DataType.DateTime:
                    case DataType.Timestamp:
                        dic.Add(item.Code, DateTime.Now.AddDays(random.Next(-90, 1)).ToString("yyyy-MM-dd HH:mm:ss"));
                        break;
                    case DataType.Binary:
                    case DataType.String:
                        if (item.IsPrimaryKey)
                        {
                            dic.Add(item.Code, System.Guid.NewGuid().ToString());
                        }
                        else if (item.Length > item.Name.Length + 1 || item.Length == 0)
                        {
                            if (index == 0)
                                dic.Add(item.Code, item.Name);
                            else
                                dic.Add(item.Code, item.Name + index);
                        }
                        else
                        {
                            StringBuilder s = new StringBuilder();
                            var t = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz".ToArray();
                            int stringLength = item.Length > 10 ? 10 : item.Length;
                            for (var j = 0; j < stringLength; j++)
                                s.Append(t[random.Next(t.Length)]);
                            dic.Add(item.Code, s.ToString());
                        }
                        break;
                    case DataType.Record:
                    case DataType.List:
                        InitRecord(item.Entity, dic, random, index);
                        break;
                }
            }
        }
        /// <summary>
        /// 发送待办
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="bizId"></param>
        /// <param name="subject"></param>
        /// <param name="expDate"></param>
        /// <returns></returns>
        public object SendDingDingToDo(string userId, string bizId, string subject, string expDate)
        {
            Dictionary<string, string> parameter = new Dictionary<string, string>();
            Dictionary<string, object> toDo = new Dictionary<string, object>();
            toDo.Add("userId", userId);
            toDo.Add("BizId", bizId);
            toDo.Add("subject", subject);
            toDo.Add("expDate", ConvertToDateTime(expDate));
            parameter.Add("toDo", JsonConvert.SerializeObject(toDo));
            TResponse<object> response = new SGHttpClient(true).PostCurrentIDC<object>("TTP-DingDingToDo-Create", parameter, 30);
            if (response.state == "1")
            {
                return response.data;
            }
            return null;
        }
        /// <summary>
        /// 更新待办
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="bizId"></param>
        /// <param name="subject"></param>
        /// <param name="expDate"></param>
        /// <returns></returns>
        public object UpdateDingDingToDo(string userId, string bizId, string subject, string expDate, bool done)
        {
            Dictionary<string, string> parameter = new Dictionary<string, string>();
            Dictionary<string, object> toDo = new Dictionary<string, object>();
            toDo.Add("userId", userId);
            toDo.Add("BizId", bizId);
            toDo.Add("subject", subject);
            if (done)
            {
                toDo.Add("done", done);
            }
            toDo.Add("expDate", ConvertToDateTime(expDate));
            parameter.Add("toDo", JsonConvert.SerializeObject(toDo));
            TResponse<object> response = new SGHttpClient(true).PostCurrentIDC<object>("TTP-DingDingToDo-Create", parameter, 30);
            if (response.state == "1")
            {
                return response.data;
            }
            return null;
        }
        /// <summary>
        /// 移除待办
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="bizId"></param>
        /// <param name="subject"></param>
        /// <param name="expDate"></param>
        /// <returns></returns>
        public object RemoveDingDingToDo(string userId, string bizId, string subject, string expDate)
        {
            Dictionary<string, string> parameter = new Dictionary<string, string>();
            Dictionary<string, object> toDo = new Dictionary<string, object>();
            toDo.Add("userId", userId);
            toDo.Add("BizId", bizId);
            toDo.Add("subject", subject);
            toDo.Add("expDate", ConvertToDateTime(expDate));
            parameter.Add("toDo", JsonConvert.SerializeObject(toDo));
            TResponse<object> response = new SGHttpClient(true).PostCurrentIDC<object>("TTP-DingDingToDo-Create", parameter, 30);
            if (response.state == "1")
            {
                return response.data;
            }
            return null;
        }
        private void SendMsgToGroup(string title, string content, List<string> mobiles, string accessToken, string secret, bool isAtAll = false)
        {
            DingDing.DingDingUtil.SendMarkDownMsg(title, content, mobiles, accessToken, secret: secret, isAtAll);
        }

        public string SerializeObject(object obj)
        {
            return JsonConvert.SerializeObject(obj, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
        }

        public Language GetCurrentLanguage()
        {
            return AppContext.Current.Language;
        }
        /// <summary>
        /// 获取支持的语言
        /// </summary>
        /// <returns></returns>
        public List<Language> GetSupportLanguages()
        {
            return LanguageService.GetSupportLanguages();
        }
        /// <summary>
        /// 根据i18NCode获取映射字段  Funcs.GetI18NColumnCode("zh-HK") = "Lang1"
        /// </summary>
        /// <param name="i18NCode"></param>
        /// <returns></returns>
        public string GetI18NColumnCode(string i18NCode)
        {
            List<Language> languages = LanguageService.GetSupportLanguages();
            Language language = languages.FirstOrDefault(t => t.ID == i18NCode);
            return language != null ? language.RepositoryCode : "";
        }
        /// <summary>
        /// 根据映射字段获取i18Ncode Funcs.GetI18NCode("Lang1") = "zh-HK"
        /// </summary>
        /// <param name="repositoryCode"></param>
        /// <returns></returns>
        public string GetI18NCode(string repositoryCode)
        {
            List<Language> languages = LanguageService.GetSupportLanguages();
            Language language = languages.FirstOrDefault(t => t.RepositoryCode == repositoryCode);
            return language != null ? language.ID : "";
        }
        public JToken NewJToken(string obj)
        {
            return JToken.Parse(obj);
        }
        private List<TRecord> Desensitize(List<TRecord> rows,List<DesensitizationColumnSet> setlist)
        {
            var desensitizationDto = new DesensitizationDto()
            {
                ColumnSets = setlist
            };
            return Maskservice.Current.DesensitzeValue(desensitizationDto, rows);
        }
        /// <summary>
        /// 构造高级查询结构
        /// </summary>
        /// <param name="filters"></param>
        /// <returns></returns>
        private string BuildDQAdvFilter(List<AdvFilter> filters)
        {
            Base.Entity.Group group = new Base.Entity.Group();
            if (filters.Count == 0)
            {
                return "{\"ElementType\":\"Group\",\"Filters\":[]}";
            }
            else
            {
                foreach (var item in filters)
                {
                    List<string> list = new List<string>();
                    list.Add(item.Value);
                    Filter filter = new Filter { Code = item.Code, Condition = item.Condition, Value = list };
                    if (group.Filters == null) //添加高级查询标识
                    {
                        group.AddFilter(filter);
                    }
                    else
                    {
                        group.AddFilter(new FRelation { Relation = "and" }, filter);
                    }
                }
            }

            return JsonConvert.SerializeObject(group);
        }

        #endregion
        #region Email
        public bool EmailAddressValidate(string str)
        {
            var reg = new Regex("^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$");
            if (reg.IsMatch(str))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion
    }

    public class AdvFilter
    {
        public string Code
        {
            get;
            set;
        }

        public string Condition
        {
            get;
            set;
        }

        public string Value
        {
            get;
            set;
        }
    }
}